package com.cg.design.graphicdesignpattern.memento;

import com.cg.design.graphicdesignpattern.memento.game.Gamer;
import com.cg.design.graphicdesignpattern.memento.game.Memento;
import org.junit.Test;

import java.io.*;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;

/**
 * Memento备忘录模式测试类
 *
 * @program: LeetCode->MementoTest
 * @description: Memento备忘录模式测试类
 * @author: cg
 * @create: 2022-04-01 10:26
 **/
public class MementoTest {

    public static final String SAVEFILENAME = "src\\com\\cg\\design\\memento\\game.dat";

    @Test
    public void testMemento() {
        // 最初的所持金钱数为100
        Gamer gamer = new Gamer(100);
        // 从文件中读取其实状态
        Memento memento = loadMemento();
        if (memento != null) {
            System.out.println("读取存档开始游戏");
            gamer.restoreMemento(memento);
        } else {
            System.out.println("新游戏");
            memento = gamer.createMemento();
        }
        for (int i = 0; i < 100; i++) {
            // 显示掷骰子的次数
            System.out.println("==== " + i);
            // 显示主人公当前的状态
            System.out.println("当前状态: " + gamer);
            // 进行游戏
            gamer.bet();
            System.out.println("所持金钱为 " + gamer.getMoney() + "元");
            // 决定如何处理Memento
            if (gamer.getMoney() > memento.getMoney()) {
                System.out.println("\t(所持金钱增加了许多，因此保存游戏当前的状态)");
                memento = gamer.createMemento();
                // 保存至文件
                saveMemento(memento);
            } else if (gamer.getMoney() < memento.getMoney()) {
                System.out.println("\t(所持金钱减少了许多，因此将游戏恢复至以前的状态)");
                gamer.restoreMemento(memento);
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("");
        }
    }

    /**
     * 保存Memento至文件
     * @param memento
     */
    public static void saveMemento(Memento memento) {
        try {
            // DeflaterOutputStream压缩数据
            ObjectOutput out = new ObjectOutputStream(new DeflaterOutputStream(new FileOutputStream(SAVEFILENAME)));
            out.writeObject(memento);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从文件中加载Memento
     * @return
     */
    public static Memento loadMemento() {
        Memento memento = null;
        try {
            // InflaterInputStream解压数据
            ObjectInput in = new ObjectInputStream(new InflaterInputStream(new FileInputStream(SAVEFILENAME)));
            memento = (Memento) in.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return memento;
    }

}
